package com.b2c.ftysys.sevice.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang.StringUtils;
import org.directwebremoting.annotations.RemoteProxy;
import org.directwebremoting.create.NewCreator;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.b2c.ftysys.constants.FtySysConstants;
import com.b2c.ftysys.dao.B2cFsyWipDAO;
import com.b2c.ftysys.dao.DatabaseException;
import com.b2c.ftysys.dao.OrderDAO;
import com.b2c.ftysys.dao.PdtorderDAO;
import com.b2c.ftysys.dao.ProductDAO;
import com.b2c.ftysys.domain.B2cFsyWd;
import com.b2c.ftysys.domain.ExampleFactory;
import com.b2c.ftysys.domain.FtyWipExample;
import com.b2c.ftysys.domain.Order;
import com.b2c.ftysys.domain.OrderExample;
import com.b2c.ftysys.domain.PageResult;
import com.b2c.ftysys.domain.Pdtorder;
import com.b2c.ftysys.domain.PdtorderExample;
import com.b2c.ftysys.domain.Product;
import com.b2c.ftysys.helper.ObjectUtils;
import com.b2c.ftysys.helper.ProductUtils;
import com.b2c.ftysys.sevice.OrderReviewService;
import com.b2c.ftysys.sevice.RouteService;
import com.b2c.ftysys.sevice.ServicesException;
import com.b2c.ftysys.view.application.AppErrorException;
import com.b2c.ftysys.view.application.fileImport.FileImport;
import com.b2c.ftysys.vo.OrderItemVo;
import com.b2c.ftysys.vo.OrderVo;

@Service
@RemoteProxy(creator = NewCreator.class, name = "reviewServices")
public class OrderReviewServiceImpl implements OrderReviewService {

	@Autowired
	private PdtorderDAO pdtOrderDao = null;

	@Autowired
	private OrderDAO orderDao = null;

	@Autowired
	private ProductDAO productDao = null;

	@Autowired
	private B2cFsyWipDAO wipDao = null;

	@Autowired
	private RouteService routeServices = null;

	@Resource(name = "orderFileImportor")
	private FileImport orderFileImportor = null;

	private String errorMess;

	private static Map<String, List<Pdtorder>> cache = new HashMap<String, List<Pdtorder>>();
	public static final int CACHE_SIZE = 150;

	public static void clearCache() {
		cache.clear();
	}

	public PdtorderDAO getPdtOrderDao() {
		return pdtOrderDao;
	}

	public void setPdtOrderDao(PdtorderDAO pdtOrderDao) {
		this.pdtOrderDao = pdtOrderDao;
	}

	public void flushCache() {
		for (String key : cache.keySet()) {
			cache.put(key, queryOrder(key));
		}
	}

	private List<Pdtorder> queryOrder(String Sku) {
		if (Sku == null || Sku.trim().length() <= 0)
			return null;
		PdtorderExample example = new PdtorderExample();
		example.createCriteria().andCmtpdtorderidEqualTo(Sku);
		return pdtOrderDao.selectByExample(example);
	}

	public List<Pdtorder> getOrderItems(String Sku) {
		if (Sku == null || Sku.trim().length() <= 0)
			return null;
		if (cache.containsKey(Sku)) {
			return cache.get(Sku);
		} else {
			List<Pdtorder> dataList = queryOrder(Sku);
			if (cache.keySet() != null && cache.keySet().size() <= CACHE_SIZE
					&& dataList != null)
				cache.put(Sku, dataList);
			return dataList;
		}
	}

	public List<Pdtorder> getOrderItemList(String[] Skus) {
		if (Skus == null || Skus.length <= 0)
			return null;

		List<Pdtorder> dataList = new ArrayList<Pdtorder>();
		for (String sku : Skus) {
			List<Pdtorder> temp = getOrderItems(sku);
			if (temp != null && temp.size() > 0) {
				dataList.addAll(temp);
			}
		}
		return dataList;
	}

	public PageResult getOrderItemList(String orderId, PageResult page) {
		if (null == page || !(page.getSqlParamObj() instanceof PdtorderExample))
			return null;
		PdtorderExample pdtorderExample = (PdtorderExample) page
				.getSqlParamObj();
		pdtorderExample.createCriteria().andOrderidEqualTo(orderId);
		return getOrderItemList(page);
	}

	public PageResult getOrderList(PageResult page) {
		page.setCountMappedId("order.abatorgenerated_countByExample");
		page.setSelectDataMappedId("order.abatorgenerated_selectByExample");

		try {
			return this.orderDao.getListByPage(page);
		} catch (DatabaseException e) {
			e.printStackTrace();
			return null;
		}
	}

	public Order getOrder(Long orderId) {
		return this.orderDao.selectByPrimaryKey(orderId);
	}

	public PageResult getOrderItemList(PageResult page) {
		page.setCountMappedId("pdtorder.abatorgenerated_countByExample");
		page.setSelectDataMappedId("pdtorder.abatorgenerated_selectByExample");

		try {
			return this.pdtOrderDao.getListByPage(page);
		} catch (DatabaseException e) {
			e.printStackTrace();
			return null;
		}
	}

	public Pdtorder getOrderItem(Long itemId) {
		return this.pdtOrderDao.selectByPrimaryKey(itemId);
	}

	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
	public int saveOrder(OrderVo vo) {
		OrderExample orderExample = ExampleFactory.createOrderExample();
		orderExample.createCriteria().andCmtorderidEqualTo(vo.getCmtorderid());
		int ftyItems = 0;

		if (this.orderDao.countByExample(orderExample) <= 0) {
			Order order = new Order();
			BeanUtils.copyProperties(vo, order);

			if (null == order.getOrderstatus()) {
				order.setOrderstatus(Order.ORDER_ON_PROCESS);
			}
			// 先保存客户订单信息
			this.orderDao.save(order);
		}

		if (null != vo.getOrderItems() && !vo.getOrderItems().isEmpty()) {
			for (OrderItemVo itemVo : vo.getOrderItems()) {
				PdtorderExample pdtExample = ExampleFactory
						.createPdtOrderExample();
				PdtorderExample.Criteria pdtCriteria = pdtExample
						.createCriteria();
				pdtCriteria.andCmtpdtorderidEqualTo(itemVo.getCmtpdtorderid());// 客户SKU
				pdtCriteria.andOrderidEqualTo(itemVo.getOrderid());// 客户订单号

				if (this.pdtOrderDao.countByExample(pdtExample) <= 0) {
					Pdtorder param = new Pdtorder();
					BeanUtils.copyProperties(itemVo, param);
					Long pdtOrderId = this.pdtOrderDao.save(param);

					// 每保存一个订购产品,都需要生成对应工厂产品
					Product product = null;
					for (int i = 0; i < param.getOrdernum(); i++) {
						product = new Product();
						product.setPdtOrderid(pdtOrderId.intValue());
						product.setCmtpdtskuid(param.getCmtpdtorderid());
						product.setCmtpdtid(param.getCmtpdtid());
						product.setCmtOrderId(vo.getCmtorderid());

						//自动匹配预设路由
						B2cFsyWd wd = routeServices.getRouteSettingBySku(param
								.getCmtpdtorderid());
						if (null != wd && null != wd.getRouteType())
							product.setRouteId(wd.getRouteType());

						ftyItems++;

						if (param.getOrdernum() > 1) {// 出现数量不为1的产品 即配件
							product.setPdtskuid(ProductUtils
									.generateFtySkuByCmtSku(param
											.getCmtpdtorderid(), vo
											.getCmtorderid(), vo.getTotalNum(),
											param.getTrackNo(), (i + 1)));
						} else {
							product.setPdtskuid(ProductUtils
									.generateFtySkuByCmtSku(param
											.getCmtpdtorderid(), vo
											.getCmtorderid(), vo.getTotalNum(),
											param.getTrackNo()));
						}

						// ftyItems++;
						productDao.save(product);
					}
				} else
					continue;
			}
		}
		return ftyItems;
	}

	/**
	 * 导入订单文件，程序自动添加路径前缀，参数只需给予文件名称即可。注意：此方法只提供给Dwr使用
	 * 
	 * @param fileAddr
	 *            导入文件的文件名
	 * @param session
	 * @return
	 * @throws ServicesException
	 */
	public int ImportExcel(String fileAddr, HttpSession session)
			throws ServicesException {
		return this.saveOrder(imortReview(session.getServletContext()
				.getRealPath("/")
				+ FtySysConstants.IMPORT_EXCEL_FILE_PREFIX + fileAddr));
	}

	/**
	 * 更新订单结束标示
	 */
	public void makeUpOrder() {
		OrderExample example = ExampleFactory.createOrderExample();
		example.createCriteria()
				.andOrderstatusNotEqualTo(Order.ORDER_DONE + "");
		PageResult page = new PageResult();
		page.setSqlParamObj(example);

		page = this.getOrderList(page);
		// 每次执行100条记录
		page.setPageSize(100);
		page.setCurPage(1);
		do {
			for (Object obj : page.getPageList()) {
				if (obj instanceof Order) {
					Order order = (Order) obj;
					if (this.checkOrderIsDone(order)) {
						this.updateOrderStatus(order, Order.ORDER_DONE);
					}
				} else {
					continue;
				}
			}
			// 翻页来执行
			page.setCurPage(page.getCurPage() + 1);
		} while (page.getCurPage() == page.getPageCnt());
	}

	public boolean checkOrderIsDone(Order order) {
		if (null == order || null == order.getOrderid())
			return false;

		FtyWipExample example = ExampleFactory.createFtyWipExample();
		example.createCriteria().andCmtOrderIdEqualTo(order.getCmtorderid())
				.andPdtStatusNotEqualTo(Product.DONE);

		// 判断是否
		if (wipDao.countByExample(example) > 0)
			return false;
		else
			return true;
	}

	/**
	 * 变更订单的状态
	 * 
	 * @param order
	 *            订单实体
	 * @param status
	 *            状态代码
	 */
	public void updateOrderStatus(Order order, int status) {
		if (null == order || null == order.getOrderid())
			return;

		order = this.getOrder(order.getOrderid());
		order.setOrderstatus(status);

		this.orderDao.updateByPrimaryKeySelective(order);
	}

	public OrderVo imortReview(String fileAddr) throws ServicesException {
		List<Map<String, Object>> dataList = null;
		try {
			dataList = orderFileImportor.importData(fileAddr);

			OrderVo orderVo = new OrderVo();
			OrderItemVo itemVo = null;
			boolean first = true;
			int totalNum = 0;
			for (Map<String, Object> dataMap : dataList) {
				try {
					if (first) {
						orderVo = (OrderVo) ObjectUtils.mapToObj(dataMap,
								OrderVo.class);
						first = false;
					}
					itemVo = (OrderItemVo) ObjectUtils.mapToObj(dataMap,
							OrderItemVo.class);

					if (null != itemVo
							&& !StringUtils.isEmpty(itemVo.getCmtpdtorderid())) {
						totalNum += itemVo.getOrdernum();
						orderVo.addItem(itemVo);
					}
				} catch (Exception e) {
					e.printStackTrace();
					errorMess += "{[订单号:" + orderVo.getCmtorderid() + "]"
							+ itemVo.getCmtpdtorderid() + "导入失败!}";
					continue;
				}
			}
			orderVo.setTotalNum(totalNum);
			orderVo.setFileAddr(fileAddr);
			return orderVo;
		} catch (AppErrorException e1) {
			e1.printStackTrace();
			throw new ServicesException(e1.getMessage());
		}
	}

	public String getErrorMess() {
		return errorMess;
	}

	public void setErrorMess(String errorMess) {
		this.errorMess = errorMess;
	}

}
